package cn.iocoder.yudao.module.system.controller.admin.examscore.vo;

import com.alibaba.excel.annotation.ExcelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;

/**
 * 新高考成绩导入 Excel VO
 * 支持新高考改革的完整数据结构，包括选科组合、赋分制度、多维度排名等
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class NewExamScoreImportExcelVO {

    /**
     * 考试ID（导入时设置）
     */
    private Long examId;

    /**
     * 学生ID（导入时设置）
     */
    private Long studentId;

    /**
     * 班级ID（导入时设置）
     */
    private Long classId;

    // ========== 基础信息 ==========
    
    @ExcelProperty("考号")
    private String examNo;

    @ExcelProperty("姓名")
    @NotBlank(message = "姓名不能为空")
    private String studentName;

    @ExcelProperty("班级")
    @NotBlank(message = "班级不能为空")
    private String className;

    @ExcelProperty("选科组合")
    @NotBlank(message = "选科组合不能为空")
    private String subjectCombination;

    @ExcelProperty("不计分科目")
    private String nonScoringSubjects;

    // ========== 总分信息 ==========
    
    @ExcelProperty("原始分")
    @NotNull(message = "总分原始分不能为空")
    private BigDecimal totalOriginalScore;

    @ExcelProperty("赋分")
    private BigDecimal totalAssignedScore;

    @ExcelProperty("总分联考排名")
    private Integer totalUnionRank;

    @ExcelProperty("组合排名")
    private Integer combinationRank;

    @ExcelProperty("校内排名")
    private Integer schoolRank;

    @ExcelProperty("班级排名")
    private Integer classRank;

    // ========== 语文成绩 ==========
    
    @ExcelProperty("语文原始分")
    private BigDecimal chineseOriginalScore;

    @ExcelProperty("语文联考排名")
    private Integer chineseUnionRank;

    @ExcelProperty("语文校内排名")
    private Integer chineseSchoolRank;

    @ExcelProperty("语文班级排名")
    private Integer chineseClassRank;

    // ========== 数学成绩 ==========
    
    @ExcelProperty("数学原始分")
    private BigDecimal mathOriginalScore;

    @ExcelProperty("数学联考排名")
    private Integer mathUnionRank;

    @ExcelProperty("数学校内排名")
    private Integer mathSchoolRank;

    @ExcelProperty("数学班级排名")
    private Integer mathClassRank;

    // ========== 英语成绩 ==========
    
    @ExcelProperty("英语原始分")
    private BigDecimal englishOriginalScore;

    @ExcelProperty("英语联考排名")
    private Integer englishUnionRank;

    @ExcelProperty("英语校内排名")
    private Integer englishSchoolRank;

    @ExcelProperty("英语班级排名")
    private Integer englishClassRank;

    // ========== 物理成绩 ==========
    
    @ExcelProperty("物理原始分")
    private BigDecimal physicsOriginalScore;

    @ExcelProperty("物理联考排名")
    private Integer physicsUnionRank;

    @ExcelProperty("物理校内排名")
    private Integer physicsSchoolRank;

    @ExcelProperty("物理班级排名")
    private Integer physicsClassRank;

    // ========== 化学成绩 ==========
    
    @ExcelProperty("化学原始分")
    private BigDecimal chemistryOriginalScore;

    @ExcelProperty("化学赋分")
    private BigDecimal chemistryAssignedScore;

    @ExcelProperty("化学赋分等级")
    private String chemistryGradeLevel;

    @ExcelProperty("化学联考排名")
    private Integer chemistryUnionRank;

    @ExcelProperty("化学校内排名")
    private Integer chemistrySchoolRank;

    @ExcelProperty("化学班级排名")
    private Integer chemistryClassRank;

    // ========== 生物成绩 ==========
    
    @ExcelProperty("生物原始分")
    private BigDecimal biologyOriginalScore;

    @ExcelProperty("生物赋分")
    private BigDecimal biologyAssignedScore;

    @ExcelProperty("生物赋分等级")
    private String biologyGradeLevel;

    @ExcelProperty("生物联考排名")
    private Integer biologyUnionRank;

    @ExcelProperty("生物校内排名")
    private Integer biologySchoolRank;

    @ExcelProperty("生物班级排名")
    private Integer biologyClassRank;

    // ========== 政治成绩 ==========
    
    @ExcelProperty("政治原始分")
    private BigDecimal politicsOriginalScore;

    @ExcelProperty("政治赋分")
    private BigDecimal politicsAssignedScore;

    @ExcelProperty("政治赋分等级")
    private String politicsGradeLevel;

    @ExcelProperty("政治联考排名")
    private Integer politicsUnionRank;

    @ExcelProperty("政治校内排名")
    private Integer politicsSchoolRank;

    @ExcelProperty("政治班级排名")
    private Integer politicsClassRank;

    // ========== 历史成绩 ==========
    
    @ExcelProperty("历史原始分")
    private BigDecimal historyOriginalScore;

    @ExcelProperty("历史赋分")
    private BigDecimal historyAssignedScore;

    @ExcelProperty("历史赋分等级")
    private String historyGradeLevel;

    @ExcelProperty("历史联考排名")
    private Integer historyUnionRank;

    @ExcelProperty("历史校内排名")
    private Integer historySchoolRank;

    @ExcelProperty("历史班级排名")
    private Integer historyClassRank;

    // ========== 地理成绩 ==========
    
    @ExcelProperty("地理原始分")
    private BigDecimal geographyOriginalScore;

    @ExcelProperty("地理赋分")
    private BigDecimal geographyAssignedScore;

    @ExcelProperty("地理赋分等级")
    private String geographyGradeLevel;

    @ExcelProperty("地理联考排名")
    private Integer geographyUnionRank;

    @ExcelProperty("地理校内排名")
    private Integer geographySchoolRank;

    @ExcelProperty("地理班级排名")
    private Integer geographyClassRank;

    // ========== 俄语成绩 ==========
    
    @ExcelProperty("俄语原始分")
    private BigDecimal russianOriginalScore;

    @ExcelProperty("俄语赋分")
    private BigDecimal russianAssignedScore;

    @ExcelProperty("俄语赋分等级")
    private String russianGradeLevel;

    @ExcelProperty("俄语联考排名")
    private Integer russianUnionRank;

    @ExcelProperty("俄语校内排名")
    private Integer russianSchoolRank;

    @ExcelProperty("俄语班级排名")
    private Integer russianClassRank;

    // ========== 日语成绩 ==========
    
    @ExcelProperty("日语原始分")
    private BigDecimal japaneseOriginalScore;

    @ExcelProperty("日语赋分")
    private BigDecimal japaneseAssignedScore;

    @ExcelProperty("日语赋分等级")
    private String japaneseGradeLevel;

    @ExcelProperty("日语联考排名")
    private Integer japaneseUnionRank;

    @ExcelProperty("日语校内排名")
    private Integer japaneseSchoolRank;

    @ExcelProperty("日语班级排名")
    private Integer japaneseClassRank;

    // ========== 西班牙语成绩 ==========
    
    @ExcelProperty("西班牙语原始分")
    private BigDecimal spanishOriginalScore;

    @ExcelProperty("西班牙语赋分")
    private BigDecimal spanishAssignedScore;

    @ExcelProperty("西班牙语赋分等级")
    private String spanishGradeLevel;

    @ExcelProperty("西班牙语联考排名")
    private Integer spanishUnionRank;

    @ExcelProperty("西班牙语校内排名")
    private Integer spanishSchoolRank;

    @ExcelProperty("西班牙语班级排名")
    private Integer spanishClassRank;

    // ========== 最高分信息 ==========
    
    @ExcelProperty("第一高分科目")
    private String firstTopSubject;

    @ExcelProperty("第一高分原始分")
    private BigDecimal firstTopOriginalScore;

    @ExcelProperty("第一高分赋分")
    private BigDecimal firstTopAssignedScore;

    @ExcelProperty("第一高分联考排名")
    private Integer firstTopUnionRank;

    @ExcelProperty("第一高分校内排名")
    private Integer firstTopSchoolRank;

    @ExcelProperty("第一高分班级排名")
    private Integer firstTopClassRank;

    // ========== 第二高分 ==========
    
    @ExcelProperty("第二高分科目")
    private String secondTopSubject;

    @ExcelProperty("第二高分原始分")
    private BigDecimal secondTopOriginalScore;

    @ExcelProperty("第二高分赋分")
    private BigDecimal secondTopAssignedScore;

    @ExcelProperty("第二高分联考排名")
    private Integer secondTopUnionRank;

    @ExcelProperty("第二高分校内排名")
    private Integer secondTopSchoolRank;

    @ExcelProperty("第二高分班级排名")
    private Integer secondTopClassRank;

    // ========== 辅助方法 ==========
    
    /**
     * 获取学号（从考号中提取或使用默认规则）
     */
    public String getStudentNo() {
        if (examNo != null && !examNo.isEmpty()) {
            return examNo;
        }
        // 如果没有考号，可以根据班级和姓名生成学号
        return className + "_" + studentName;
    }

    /**
     * 检查是否为选考科目
     */
    public boolean isSubjectSelected(String subjectName) {
        if (subjectCombination == null || subjectCombination.isEmpty()) {
            return false;
        }
        return subjectCombination.contains(subjectName);
    }

    /**
     * 检查是否为不计分科目
     */
    public boolean isNonScoringSubject(String subjectName) {
        if (nonScoringSubjects == null || nonScoringSubjects.isEmpty()) {
            return false;
        }
        return nonScoringSubjects.contains(subjectName);
    }

    /**
     * 检查科目是否应该参与总分计算
     * 不计分科目不参与总分计算
     */
    public boolean shouldIncludeInTotal(String subjectName) {
        return !isNonScoringSubject(subjectName);
    }

    /**
     * 获取不计分科目列表
     */
    public String[] getNonScoringSubjectsList() {
        if (nonScoringSubjects == null || nonScoringSubjects.isEmpty()) {
            return new String[0];
        }
        return nonScoringSubjects.split("[,，;；\\s]+");
    }

    /**
     * 获取指定科目的原始分
     */
    public BigDecimal getSubjectOriginalScore(String subjectName) {
        switch (subjectName) {
            case "语文": return chineseOriginalScore;
            case "数学": return mathOriginalScore;
            case "英语": return englishOriginalScore;
            case "物理": return physicsOriginalScore;
            case "化学": return chemistryOriginalScore;
            case "生物": return biologyOriginalScore;
            case "政治": return politicsOriginalScore;
            case "历史": return historyOriginalScore;
            case "地理": return geographyOriginalScore;
            case "俄语": return russianOriginalScore;
            case "日语": return japaneseOriginalScore;
            case "西班牙语": return spanishOriginalScore;
            default: return null;
        }
    }

    /**
     * 获取指定科目的赋分
     */
    public BigDecimal getSubjectAssignedScore(String subjectName) {
        switch (subjectName) {
            case "化学": return chemistryAssignedScore;
            case "生物": return biologyAssignedScore;
            case "政治": return politicsAssignedScore;
            case "历史": return historyAssignedScore;
            case "地理": return geographyAssignedScore;
            case "俄语": return russianAssignedScore;
            case "日语": return japaneseAssignedScore;
            case "西班牙语": return spanishAssignedScore;
            default: return null;
        }
    }

    /**
     * 获取指定科目的等级
     */
    public String getSubjectGradeLevel(String subjectName) {
        switch (subjectName) {
            case "化学": return chemistryGradeLevel;
            case "生物": return biologyGradeLevel;
            case "政治": return politicsGradeLevel;
            case "历史": return historyGradeLevel;
            case "地理": return geographyGradeLevel;
            case "俄语": return russianGradeLevel;
            case "日语": return japaneseGradeLevel;
            case "西班牙语": return spanishGradeLevel;
            default: return null;
        }
    }

    /**
     * 获取指定科目的校内排名
     */
    public Integer getSubjectSchoolRank(String subjectName) {
        switch (subjectName) {
            case "语文": return chineseSchoolRank;
            case "数学": return mathSchoolRank;
            case "英语": return englishSchoolRank;
            case "物理": return physicsSchoolRank;
            case "化学": return chemistrySchoolRank;
            case "生物": return biologySchoolRank;
            case "政治": return politicsSchoolRank;
            case "历史": return historySchoolRank;
            case "地理": return geographySchoolRank;
            case "俄语": return russianSchoolRank;
            case "日语": return japaneseSchoolRank;
            case "西班牙语": return spanishSchoolRank;
            default: return null;
        }
    }

    /**
     * 获取指定科目的班级排名
     */
    public Integer getSubjectClassRank(String subjectName) {
        switch (subjectName) {
            case "语文": return chineseClassRank;
            case "数学": return mathClassRank;
            case "英语": return englishClassRank;
            case "物理": return physicsClassRank;
            case "化学": return chemistryClassRank;
            case "生物": return biologyClassRank;
            case "政治": return politicsClassRank;
            case "历史": return historyClassRank;
            case "地理": return geographyClassRank;
            case "俄语": return russianClassRank;
            case "日语": return japaneseClassRank;
            case "西班牙语": return spanishClassRank;
            default: return null;
        }
    }
    
    /**
     * 获取指定科目的联考排名
     */
    public Integer getSubjectUnionRank(String subjectName) {
        switch (subjectName) {
            case "语文": return chineseUnionRank;
            case "数学": return mathUnionRank;
            case "英语": return englishUnionRank;
            case "物理": return physicsUnionRank;
            case "化学": return chemistryUnionRank;
            case "生物": return biologyUnionRank;
            case "政治": return politicsUnionRank;
            case "历史": return historyUnionRank;
            case "地理": return geographyUnionRank;
            case "俄语": return russianUnionRank;
            case "日语": return japaneseUnionRank;
            case "西班牙语": return spanishUnionRank;
            default: return null;
        }
    }

    /**
     * 检查数据完整性
     */
    public boolean isDataComplete() {
        return studentName != null && !studentName.isEmpty() &&
               className != null && !className.isEmpty();
    }

    /**
     * 获取主科成绩（语数英）
     */
    public BigDecimal getMainSubjectsTotal() {
        BigDecimal total = BigDecimal.ZERO;
        if (chineseOriginalScore != null) {
            total = total.add(chineseOriginalScore);
        }
        if (mathOriginalScore != null) {
            total = total.add(mathOriginalScore);
        }
        if (englishOriginalScore != null) {
            total = total.add(englishOriginalScore);
        }
        return total;
    }

    /**
     * 获取选考科目总分（赋分后）
     * 排除不计分科目
     */
    public BigDecimal getSelectedSubjectsTotal() {
        BigDecimal total = BigDecimal.ZERO;
        
        if (isSubjectSelected("物理") && shouldIncludeInTotal("物理") && physicsOriginalScore != null) {
            total = total.add(physicsOriginalScore);
        }
        if (isSubjectSelected("化学") && shouldIncludeInTotal("化学") && chemistryAssignedScore != null) {
            total = total.add(chemistryAssignedScore);
        }
        if (isSubjectSelected("生物") && shouldIncludeInTotal("生物") && biologyAssignedScore != null) {
            total = total.add(biologyAssignedScore);
        }
        if (isSubjectSelected("政治") && shouldIncludeInTotal("政治") && politicsAssignedScore != null) {
            total = total.add(politicsAssignedScore);
        }
        if (isSubjectSelected("历史") && shouldIncludeInTotal("历史") && historyAssignedScore != null) {
            total = total.add(historyAssignedScore);
        }
        if (isSubjectSelected("地理") && shouldIncludeInTotal("地理") && geographyAssignedScore != null) {
            total = total.add(geographyAssignedScore);
        }
        if (isSubjectSelected("俄语") && shouldIncludeInTotal("俄语") && russianAssignedScore != null) {
            total = total.add(russianAssignedScore);
        }
        if (isSubjectSelected("日语") && shouldIncludeInTotal("日语") && japaneseAssignedScore != null) {
            total = total.add(japaneseAssignedScore);
        }
        if (isSubjectSelected("西班牙语") && shouldIncludeInTotal("西班牙语") && spanishAssignedScore != null) {
            total = total.add(spanishAssignedScore);
        }
        
        return total;
    }
}